home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / c_flow.zip / CFLOW.C next >
Text File  |  1985-06-24  |  27KB  |  1,205 lines

  1. /*
  2. **   CFLOW.C : find module call structure of c program
  3. **   refer to cflow.doc for how to use
  4. **
  5. **                     Mark Ellington
  6. **                    05-27-84
  7. **
  8. **   Converted to MS-DOS 2 and C86, adding the following features:
  9. **
  10. **    1.  filename wildcard support
  11. **    2.  -l flag to include line numbers in output
  12. **    3.  -f flag to include file names in output
  13. **    4.  #include support (with -h flag, same as C86 V2.20H)
  14. **    5.  -x flag to generate input for CFLOWX
  15. **    6.  #define macro() support
  16. **    7.  -t flag to change to '\t' for indentation
  17. **    8.  -s flag to allow specification of number of indentation spaces
  18. **           (default is 4 spaces)
  19. **
  20. **                    Larry Steeger
  21. **                    06-12-85
  22. */
  23.  
  24. #include <stdio.h>        /* C86 header                */
  25.  
  26. #define    VOID int
  27.  
  28. /*    external functions    */
  29.  
  30. extern    VOID abort();
  31. extern    char *alloc();
  32. extern    VOID exit();
  33. extern    int fclose();
  34. extern    unsigned char *filewdir();
  35. extern    FILE *fopen();
  36. extern    VOID fprintf();
  37. extern    int fputs();
  38. extern    VOID free();
  39. extern    int isalnum();
  40. extern    int isdigit();
  41. extern    int isspace();
  42. extern    char *lower();
  43. extern    char *makefile();
  44. extern    char *makefnam();
  45. extern    char *makepath();
  46. extern    char *realloc();
  47. extern    VOID setmem();
  48. extern    VOID sprintf();
  49. extern    char *strcat();
  50. extern    unsigned char *strchr();
  51. extern    char *strcpy();
  52. extern    unsigned strlen();
  53. extern    int strncmp();
  54. extern    char *strncpy();
  55. extern    int tolower();
  56.  
  57. #include "cflowx.h"        /* CFLOW/CFLOWX header            */
  58.  
  59. #define    VERSION    85
  60. #define    RELEASE    06
  61. #define    MODIFIC    20
  62.  
  63. #define    outinfo(S) fputs(S,stdout)
  64.  
  65. /*    display CFLOW logo                        */
  66.  
  67. outlogo()
  68. {
  69.     outinfo("\nCFLOW --> function declarations and calls in C source");
  70.     outinfo("\nby Mark Ellington");
  71.     fprintf(stdout,
  72.         "\n[V%02d.%02d.%02d for C86 by Lawrence R. Steeger]\n",
  73.         VERSION, RELEASE, MODIFIC
  74.         );
  75. }
  76.  
  77. /*    CFLOW usage help                        */
  78.  
  79. outhelp()
  80. {
  81.     outinfo("\n  usage: cflow ");
  82.     outinfo("[-[lft]|[x]] [-hsystem[,project]] ");
  83.     outinfo("[input1[..inputn]] [>output]\n");
  84.     outinfo("\n  flags: -hsystem[,project]");
  85.     outinfo("\n              #include drive/pathname specification");
  86.     outinfo("\n              (usage: C86 V2.20H)");
  87.     outinfo("\n         -l   include line numbers in output");
  88.     outinfo("\n         -f   include file names in output");
  89.     outinfo("\n         -sn  number of indentation spaces");
  90.     outinfo("\n         -t   tabs rather than spaces for indentation");
  91.     outinfo("\n         -x   generate input for CFLOWX\n");
  92.     outinfo("\ndefaults:     cflow -s4 [input] >stdout");
  93. }
  94.  
  95. typedef    struct _cflow {        /* recursive execution structure    */
  96.  
  97.     struct _cflow *_chain;    /* previous CFLOW structure        */
  98.  
  99.     int _fnmbr,        /* current file name index        */
  100.         _level,        /* level of open "{"s or #includes    */
  101.         _prevchar,        /* previous character in input buffer    */
  102.         _curchar,        /* current character in input buffer
  103.                 ** array subscript
  104.                 */
  105.         _curline,        /* current line in input dataset    */
  106.         _define,        /* #define flag                */
  107.         _defdcl;        /* name declaration offset        */
  108.  
  109.     unsigned char _delimit,    /* #include file name delimiter        */
  110.               *_defname,/* defined name buffer            */
  111.               *_name,    /* module name buffer            */
  112.               *_ins,    /* source input line buffer        */
  113.               *_fname,    /* source file name buffer        */
  114.               *_fpname;    /* source file/pathname buffer        */
  115.  
  116.     FILE *_fptr;        /* input file pointer            */
  117.  
  118.     } CFLOW;
  119.  
  120. /*    useability macros for CFLOW structure elements            */
  121.  
  122. #define    chain cflowp->_chain
  123. #define    fnmbr cflowp->_fnmbr
  124. #define    level cflowp->_level
  125. #define prevchar cflowp->_prevchar
  126. #define    curchar cflowp->_curchar
  127. #define    curline cflowp->_curline
  128. #define    define cflowp->_define
  129. #define    defdcl cflowp->_defdcl
  130. #define    delimit cflowp->_delimit
  131. #define    defname cflowp->_defname
  132. #define    name cflowp->_name
  133. #define    ins cflowp->_ins
  134. #define    fname cflowp->_fname
  135. #define    fpname cflowp->_fpname
  136. #define    fptr cflowp->_fptr
  137.  
  138. /*    runtime flags                            */
  139.  
  140. static    int hflag = FALSE,        /* -h  #include drive/pathname    */
  141.         lflag = FALSE,        /* -l  show line numbers    */
  142.         fflag = FALSE,        /* -f  show file names        */
  143.         sflag = FALSE,        /* -s  space indentation count    */
  144.         tflag = FALSE,        /* -t  tab indentation flag    */
  145.         xflag = FALSE;        /* -x  generate CFLOWX input    */
  146.  
  147. static    int fnumber = 0,        /* C source file counter    */
  148.         flevel = 0,            /* C source file level        */
  149.         mnumber = 0;        /* C source file main counter    */
  150.  
  151. static    unsigned char *filepath = NULL,    /* default file/path name    */
  152.               *hsystem = NULL,    /* -hsystem specification    */
  153.                   *hproject = NULL,    /* -h,project specification    */
  154.               *tab = "    ";    /* -t indentation        */
  155.  
  156. static    unsigned char newLine[] = {"\n"};
  157.  
  158. static    CFLOW *cflowp = NULL;        /* current CFLOW execution ptr    */
  159.  
  160. /*    mainline                            */
  161.  
  162. main(argc,argv)
  163. int argc;
  164. unsigned char * argv[];
  165. {
  166.     unsigned char *fp,
  167.               *pp;        /* temporary file/path pointer    */
  168.  
  169.     int fcount,            /* C source file counter    */
  170.         i,
  171.         j;
  172.  
  173.     if (argc < 2) {            /* display CFLOW help        */
  174.  
  175.         outlogo();
  176.         outhelp();
  177.                 exit(1);
  178.     }
  179.  
  180.     cflowp = alloc(sizeof(CFLOW));    /* 1st execution structure    */
  181.  
  182.     name = alloc(MAXBUF);        /* module name buffer        */
  183.     ins = alloc(MAXBUF);        /* input line buffer        */
  184.     fname = alloc(MAXPATH);        /* current file name        */
  185.     fpname = alloc(MAXPATH);    /* current file/path name    */
  186.  
  187.     filepath = alloc(1);        /* dummy file/path name        */
  188.     *filepath = EOS;
  189.  
  190.     for (i=1; i < argc; i++) {    /* process all flags        */
  191.         if (*argv[i] == '-') {
  192.             flags(argv[i]);
  193.             for (j = i--, --argc; j < argc; j++)
  194.                 argv[j] = argv[j+1];
  195.         }
  196.     }
  197.  
  198.     if (!xflag) outlogo();        /* display CFLOW logo        */
  199.  
  200.     if (hsystem != NULL)        /* display -h system prefix    */
  201.         if (*hsystem)
  202.             output(HDRSYST, hsystem);
  203.  
  204.     if (hproject != NULL)        /* display -h project prefix    */
  205.         if (*hproject)
  206.             output(HDRPROJ, hproject);
  207.  
  208.     for (i=1; i < argc; i++) {    /* process all files        */
  209.         if (*argv[i]) {
  210.             fnmbr = mnumber++;
  211.             strcpy(fname, argv[i]);    /* get file name    */
  212.             lower(fname);
  213.  
  214.             free(filepath);        /* get file/path name    */
  215.             filepath = makepath(fname);
  216.  
  217.             if ((strchr(fname, '*') != NULL) /* wildcards    */
  218.             ||  (strchr(fname, '?') != NULL)) {
  219.  
  220.                 /*    process all matching file names    */
  221.  
  222.                 fcount = 0;
  223.                 while ((fp = filewdir(argv[i],0x00)) != NULL) {
  224.  
  225.                     if (!fcount) {
  226.                         pp = makepath(fname);
  227.                         output(WILDPTH, pp);
  228.                         free(pp);
  229.                         pp = makefile(fname);
  230.                         output(WILDNME, pp);
  231.                         free(pp);
  232.                     }
  233.  
  234.                     ++fcount;
  235.                     lower(fp);
  236.                     strcpy(fname,fp);
  237.                     makefnam(fp, filepath, fpname);
  238.                     flevel = level = 0;
  239.                     modules();
  240.                     free(fp);
  241.                 }
  242.  
  243.                 if (!fcount) output(WILDNF, fname);
  244.             }
  245.             else {                /* no wildcards    */
  246.                 strcpy(fpname, fname);
  247.                 strcpy(fname, (pp=makefile(fname)));
  248.                 free(pp);
  249.                 flevel = level = 0;
  250.                 modules();
  251.             }
  252.         }
  253.     }
  254.     exit(0);
  255. }
  256.  
  257. /*    process command line flags                    */
  258.  
  259. int flags(flag)
  260. unsigned char *flag;
  261. {
  262.     unsigned char *hp;
  263.  
  264.     int i;
  265.  
  266.     for (i=1; i < strlen(flag); i++)
  267.         switch (tolower(flag[i])) {
  268.  
  269.         case 'h':        /* -h header specifications    */
  270.             hflag = TRUE;
  271.             i++;
  272.  
  273.             if (hsystem != NULL)
  274.                 free(hsystem);
  275.             if ((hp = strchr(&flag[i], ',')) != NULL)
  276.                 *hp++ = EOS;
  277.             hsystem = alloc((strlen(&flag[i]) + 1));
  278.             strcpy(hsystem, lower(&flag[i]));
  279.  
  280.             if (hp) {
  281.                 if (hproject != NULL)
  282.                     free(hproject);
  283.                 hproject = alloc((strlen(hp) + 1));
  284.                 strcpy(hproject, lower(hp));
  285.             }
  286.  
  287.             i=strlen(flag); /* force break in for loop    */
  288.             break;
  289.  
  290.         case 'l':        /* -l include line numbers    */
  291.             lflag = TRUE;
  292.             break;
  293.  
  294.         case 'f':        /* -f include file names    */
  295.             fflag = TRUE;
  296.             break;
  297.  
  298.         case 's':        /* -s spaces for indentation    */
  299.             if (tflag) {
  300.                 fprintf(stdout,
  301.                     "\n-s is mutually exclusive with -t");
  302.                 outhelp();
  303.                 exit(1);
  304.             }
  305.             if (!isdigit(flag[i+1])) {    /* -s only !    */
  306.  
  307.                 /*  note: -s  implies default        */
  308.  
  309.                 sflag = strlen(tab);
  310.                 break;
  311.             }
  312.             sflag = 0;
  313.             while (isdigit(flag[++i]))
  314.                 sflag = (sflag * 10) + ((int)flag[i] - '0');
  315.             --i;
  316.  
  317.             if (sflag) {
  318.                 tab =